<template>

	<div style="height:calc(90vh);overflow-y: scroll;">

		<div class="menu" editor-component="menu">
			<div class="menu-item">
				<div class="menu-item__undo">
					<i></i>
				</div>
				<div class="menu-item__redo">
					<i></i>
				</div>
				<div class="menu-item__painter" title="格式刷(双击可连续使用)">
					<i></i>
				</div>
				<div class="menu-item__format" title="清除格式">
					<i></i>
				</div>
			</div>
			<div class="menu-divider"></div>
			<div class="menu-item">
				<div class="menu-item__font">
					<span class="select" title="字体">微软雅黑</span>
					<div class="options">
						<ul>
							<li data-family="Yahei" style="font-family:'Yahei';">微软雅黑</li>
							<li data-family="宋体" style="font-family:'宋体';">宋体</li>
							<li data-family="黑体" style="font-family:'黑体';">黑体</li>
							<li data-family="仿宋" style="font-family:'仿宋';">仿宋</li>
							<li data-family="楷体" style="font-family:'楷体';">楷体</li>
							<li data-family="等线" style="font-family:'等线';">等线</li>
							<li data-family="华文琥珀" style="font-family:'华文琥珀';">华文琥珀</li>
							<li data-family="华文楷体" style="font-family:'华文楷体';">华文楷体</li>
							<li data-family="华文隶书" style="font-family:'华文隶书';">华文隶书</li>
							<li data-family="华文新魏" style="font-family:'华文新魏';">华文新魏</li>
							<li data-family="华文行楷" style="font-family:'华文行楷';">华文行楷</li>
							<li data-family="华文中宋" style="font-family:'华文中宋';">华文中宋</li>
							<li data-family="华文彩云" style="font-family:'华文彩云';">华文彩云</li>
							<li data-family="Arial" style="font-family:'Arial';">Arial</li>
							<li data-family="Segoe UI" style="font-family:'Segoe UI';">Segoe UI</li>
							<li data-family="Ink Free" style="font-family:'Ink Free';">Ink Free</li>
							<li data-family="Fantasy" style="font-family:'Fantasy';">Fantasy</li>
						</ul>
					</div>
				</div>
				<div class="menu-item__size">
					<span class="select" title="字体">小四</span>
					<div class="options">
						<ul>
							<li data-size="56">初号</li>
							<li data-size="48">小初</li>
							<li data-size="34">一号</li>
							<li data-size="32">小一</li>
							<li data-size="29">二号</li>
							<li data-size="24">小二</li>
							<li data-size="21">三号</li>
							<li data-size="20">小三</li>
							<li data-size="18">四号</li>
							<li data-size="16">小四</li>
							<li data-size="14">五号</li>
							<li data-size="12">小五</li>
							<li data-size="10">六号</li>
							<li data-size="8">小六</li>
							<li data-size="7">七号</li>
							<li data-size="6">八号</li>
						</ul>
					</div>
				</div>
				<div class="menu-item__size-add">
					<i></i>
				</div>
				<div class="menu-item__size-minus">
					<i></i>
				</div>
				<div class="menu-item__bold">
					<i></i>
				</div>
				<div class="menu-item__italic">
					<i></i>
				</div>
				<div class="menu-item__underline">
					<i></i>
				</div>
				<div class="menu-item__strikeout" title="删除线(Ctrl+Shift+X)">
					<i></i>
				</div>
				<div class="menu-item__superscript">
					<i></i>
				</div>
				<div class="menu-item__subscript">
					<i></i>
				</div>
				<div class="menu-item__color" title="字体颜色">
					<i></i>
					<span></span>
					<input type="color" id="color" />
				</div>
				<div class="menu-item__highlight" title="高亮">
					<i></i>
					<span></span>
					<input type="color" id="highlight">
				</div>
			</div>
			<div class="menu-divider"></div>
			<div class="menu-item">
				<div class="menu-item__title">
					<i></i>
					<span class="select" title="切换标题">正文</span>
					<div class="options">
						<ul>
							<li style="font-size:16px;">正文</li>
							<li data-level="first" style="font-size:26px;">标题1</li>
							<li data-level="second" style="font-size:24px;">标题2</li>
							<li data-level="third" style="font-size:22px;">标题3</li>
							<li data-level="fourth" style="font-size:20px;">标题4</li>
							<li data-level="fifth" style="font-size:18px;">标题5</li>
							<li data-level="sixth" style="font-size:16px;">标题6</li>
						</ul>
					</div>
				</div>
				<div class="menu-item__left">
					<i></i>
				</div>
				<div class="menu-item__center">
					<i></i>
				</div>
				<div class="menu-item__right">
					<i></i>
				</div>
				<div class="menu-item__alignment">
					<i></i>
				</div>
				<div class="menu-item__row-margin">
					<i title="行间距"></i>
					<div class="options">
						<ul>
							<li data-rowmargin='1'>1</li>
							<li data-rowmargin="1.25">1.25</li>
							<li data-rowmargin="1.5">1.5</li>
							<li data-rowmargin="1.75">1.75</li>
							<li data-rowmargin="2">2</li>
							<li data-rowmargin="2.5">2.5</li>
							<li data-rowmargin="3">3</li>
						</ul>
					</div>
				</div>
				<div class="menu-item__list">
					<i></i>
					<div class="options">
						<ul>
							<li>
								<label>取消列表</label>
							</li>
							<li data-list-type="ol" data-list-style='decimal'>
								<label>有序列表：</label>
								<ol>
									<li>________</li>
								</ol>
							</li>
							<li data-list-type="ul" data-list-style='disc'>
								<label>实心圆点列表：</label>
								<ul style="list-style-type: disc;">
									<li>________</li>
								</ul>
							</li>
							<li data-list-type="ul" data-list-style='circle'>
								<label>空心圆点列表：</label>
								<ul style="list-style-type: circle;">
									<li>________</li>
								</ul>
							</li>
							<li data-list-type="ul" data-list-style='square'>
								<label>空心方块列表：</label>
								<ul style="list-style-type: square;">
									<li>________</li>
								</ul>
							</li>
						</ul>
					</div>
				</div>
			</div>
			<div class="menu-divider"></div>
			<div class="menu-item">
				<div class="menu-item__table">
					<i title="表格"></i>
				</div>
				<div class="menu-item__table__collapse">
					<div class="table-close">×</div>
					<div class="table-title">
						<span class="table-select">插入</span>
						<span>表格</span>
					</div>
					<div class="table-panel"></div>
				</div>
				<div class="menu-item__image">
					<i title="图片"></i>
					<input type="file" id="image" accept=".png, .jpg, .jpeg, .svg, .gif">
				</div>
				<div class="menu-item__hyperlink">
					<i title="超链接"></i>
				</div>
				<div class="menu-item__separator">
					<i title="分割线"></i>
					<div class="options">
						<ul>
							<li data-separator='0,0'>
								<i></i>
							</li>
							<li data-separator="1,1">
								<i></i>
							</li>
							<li data-separator="3,1">
								<i></i>
							</li>
							<li data-separator="4,4">
								<i></i>
							</li>
							<li data-separator="7,3,3,3">
								<i></i>
							</li>
							<li data-separator="6,2,2,2,2,2">
								<i></i>
							</li>
						</ul>
					</div>
				</div>
				<div class="menu-item__watermark">
					<i title="水印(添加、删除)"></i>
					<div class="options">
						<ul>
							<li data-menu="add">添加水印</li>
							<li data-menu="delete">删除水印</li>
						</ul>
					</div>
				</div>
				<div class="menu-item__codeblock" title="代码块">
					<i></i>
				</div>
				<div class="menu-item__page-break" title="分页符">
					<i></i>
				</div>
				<div class="menu-item__control">
					<i title="控件"></i>
					<div class="options">
						<ul>
							<li data-control='text'>文本</li>
							<li data-control="select">列举</li>
							<li data-control="checkbox">复选框</li>
						</ul>
					</div>
				</div>
				<div class="menu-item__checkbox" title="复选框">
					<i></i>
				</div>
				<div class="menu-item__latex" title="LateX">
					<i></i>
				</div>
				<div class="menu-item__date">
					<i title="日期"></i>
					<div class="options">
						<ul>
							<li data-format="yyyy-MM-dd"></li>
							<li data-format="yyyy-MM-dd hh:mm:ss"></li>
						</ul>
					</div>
				</div>
				<div class="menu-item__block" title="内容块">
					<i></i>
				</div>
			</div>
			<div class="menu-divider"></div>
			<div class="menu-item">
				<div class="menu-item__search" data-menu="search">
					<i></i>
				</div>
				<div class="menu-item__search__collapse" data-menu="search">
					<div class="menu-item__search__collapse__search">
						<input type="text" />
						<label class="search-result"></label>
						<div class="arrow-left">
							<i></i>
						</div>
						<div class="arrow-right">
							<i></i>
						</div>
						<span>×</span>
					</div>
					<div class="menu-item__search__collapse__replace">
						<input type="text">
						<button>替换</button>
					</div>
				</div>
				<div class="menu-item__print" data-menu="print">
					<i></i>
				</div>
				<Poptip width="400" popper-class="propClass" word-wrap="true" placement="bottom"
					@on-popper-show="aiModelShow">
					<div class="menu-item__ai" data-menu="ai">
						<i></i>
					</div>
					<template #content>
						<div class="ai">
							<Space>
								<Row>
									<Col span="24">
									<Tabs value="aimodelConfig.aiModel">
										<TabPane label="星火" name="XingHuo">
											<Row>
												<Col span="8">
												<Input type="text" v-model="aimodelConfig.appId" placeholder="appId" />
												</Col>
												<Col span="8">
												<Input type="text" v-model="aimodelConfig.apiKey"
													placeholder="apiKey" />
												</Col>
												<Col span="8">
												<Input type="text" v-model="aimodelConfig.apiSecret"
													placeholder="apiSecret" />
												</Col>
											</Row>
											<Divider />
											<Row style="height:300px;overflow-y:scroll;">
												<Col span="24">
												<List border>
													<ListItem v-for="value in aiHistory">
														{{ value.role == 'user' ? '你说：' : '服务端回复:' }}
														<div v-html="value.content" style="width:200px;"></div>
													</ListItem>
												</List>
												</Col>
											</Row>
											<Divider />
											<Row>
												<Col span="13">
												<Input type="text" @on-enter="aiSendMessage" v-model="inputMessage"
													placeholder="请输入问题" />
												</Col>
												<Col span="1">
												</Col>
												<Col span="4">
												<Button type="primary" @click="aiSendMessage">发送</Button>
												</Col>

												<Col span="4">
												<Button type="primary" @click="clearHistory">清除历史</Button>
												</Col>
											</Row>


										</TabPane>
									</Tabs>
									</Col>
								</Row>
							</Space>
						</div>
					</template>
				</Poptip>


			</div>
		</div>
		<div class="catalog" editor-component="catalog">
			<div class="catalog__header">
				<span>目录</span>
				<div class="catalog__header__close">
					<i></i>
				</div>
			</div>
			<div class="catalog__main"></div>
		</div>
		<div class="editor" ref="divRef"></div>
		<div class="comment" editor-component="comment"></div>
		<div class="footer" editor-component="footer">
			<div>
				<div class="catalog-mode" title="目录">
					<i></i>
				</div>
				<div class="page-mode">
					<i title="页面模式(分页、连页)"></i>
					<div class="options">
						<ul>
							<li data-page-mode="paging" class="active">分页</li>
							<li data-page-mode="continuity">连页</li>
						</ul>
					</div>
				</div>
				<span>可见页码：<span class="page-no-list">1</span></span>
				<span>页面：<span class="page-no">1</span>/<span class="page-size">1</span></span>
				<span>字数：<span class="word-count">0</span></span>
			</div>
			<div class="editor-mode" title="编辑模式(编辑、清洁、只读、表单)">编辑模式</div>
			<div>
				<div class="page-scale-minus" title="缩小(Ctrl+-)">
					<i></i>
				</div>
				<span class="page-scale-percentage" title="显示比例(点击可复原Ctrl+0)">100%</span>
				<div class="page-scale-add" title="放大(Ctrl+=)">
					<i></i>
				</div>
				<div class="paper-size">
					<i title="纸张类型"></i>
					<div class="options">
						<ul>
							<li data-paper-size="794*1123" class="active">A4</li>
							<li data-paper-size="1593*2251">A2</li>
							<li data-paper-size="1125*1593">A3</li>
							<li data-paper-size="565*796">A5</li>
							<li data-paper-size="412*488">5号信封</li>
							<li data-paper-size="450*866">6号信封</li>
							<li data-paper-size="609*862">7号信封</li>
							<li data-paper-size="862*1221">9号信封</li>
							<li data-paper-size="813*1266">法律用纸</li>
							<li data-paper-size="813*1054">信纸</li>
						</ul>
					</div>
				</div>
				<div class="paper-direction">
					<i title="纸张方向"></i>
					<div class="options">
						<ul>
							<li data-paper-direction="vertical" class="active">纵向</li>
							<li data-paper-direction="horizontal">横向</li>
						</ul>
					</div>
				</div>
				<div class="paper-margin" title="页边距">
					<i></i>
				</div>
				<div class="fullscreenEditor" title="全屏显示">
					<i></i>
				</div>
			</div>
		</div>

	</div>
	<!--  <div class="canvas-editor" ref="divRef"></div>-->
</template>
<script setup>
import { onMounted, ref, getCurrentInstance, watch, defineProps } from "vue";
import prism from 'prismjs';
import Editor, {
	BlockType,
	ControlType,
	EditorMode,
	EditorZone,
	ElementType,
	KeyMap,
	ListStyle,
	ListType,
	RowFlex,
} from '@hufe921/canvas-editor';
import { Dialog } from './dialog/Dialog';
import { formatPrismToken } from '../../utils/prism'
import { Signature } from './signature/Signature'
import { debounce, nextTick, scrollIntoView } from '@/utils'
import './style.css';

const props = defineProps(["value"])


const divRef = ref()
const isApple =
	typeof navigator !== 'undefined' && /Mac OS X/.test(navigator.userAgent);

const commentList = ref([
	{
		id: '1',
		content:
			'红细胞比容（HCT）是指每单位容积中红细胞所占全血容积的比值，用于反映红细胞和血浆的比例。',
		userName: 'Hufe',
		rangeText: '血细胞比容',
		createdDate: '2023-08-20 23:10:55'
	}
]);

const aimodelConfig = ref({
	aiModel: "XingHuo",
	appId: "2f915878",
	apiKey: "f30527bb4adf50be19bd5c0da6992306",
	apiSecret: "ZDEzMDA2YTY5OTljMGQyODQ3MmJkNDhk"
})

const inputMessage = ref();

const { proxy } = getCurrentInstance();
const clearHistory = () => {
	const aiModel = AiModelFactory.create(aimodelConfig.value.aiModel, aimodelConfig.value);
	if (aiModel) {
		aiModel.clearHistory();
		// proxy.$Message.info('清除成功');
	}
	aiModelShow();
}

let aiHistory = ref([]);

const aiModelShow = () => {
	const aiModel = AiModelFactory.create(aimodelConfig.value.aiModel, aimodelConfig.value);
	// const aiHistory
	const b = aiModel.getHistory();
	console.log(b)
	if (b) {
		aiHistory.value = b;
	} else {
		aiHistory.value = [];
	}

}

const aiSendMessage = () => {
	const aiModel = AiModelFactory.create(aimodelConfig.value.aiModel, aimodelConfig.value);
	if (aiModel) {
		aiModel?.start(inputMessage.value, "", (d, status) => {
			if (status == 0) {
				aiModelShow();
			}
			if (status == 2) {
				aiModelShow();
			}
			// console.log(d);
			editor.value.command.executeInsertElementList([
				{
					type: ElementType.TEXT,
					value: d
				}
			]);
		});
		inputMessage.value = '';

	} else {
		console.error("Ai model config error.")
	}

}


const editor = ref();
const init = () => {
	editor.value = new Editor(divRef.value,
		{
			header: [
				{
					value: '',
					rowFlex: RowFlex.CENTER
				}
			],
			main: [
				{
					value: ''
				}
			],
			footer: [
				{
					value: '',
					size: 12
				}
			]
		},
		{

			margins: [100, 120, 100, 120],
			// watermark: {
			//   data: 'CANVAS-EDITOR',
			//   size: 120
			// },
			pageNumber: {
				format: '第{pageNo}页/共{pageCount}页'
			},
			placeholder: {
				data: '请输入正文'
			},
			maskMargin: [60, 0, 30, 0] // 菜单栏高度60，底部工具栏30为遮盖层
		}
	);
	Reflect.set(window, 'editor', editor)
}

watch(props, (newValue, oldValue) => {
	setValue(newValue.value)
})

const setValue = (value) => {
	if (!value) {
		value = "{}";
	}
	// console.log(value)
	const c = JSON.parse(value);
	if (!c.main) {
		return
	}
	editor.value.command.executeSetValue(c);
}

const getValue = () => {
	const c = editor.value.command.getValue().data;
	return c;
}

const clear = () => {
	editor.value.command.executeSetValue({
		header: [],
		main: [],
		footer: []
	});
}

defineExpose({
	getValue,
	setValue,
	clear
})


onMounted(() => {

	init();
	bindGlobalClickEventListener();
	bindEditorTobarEvent();
	setValue(props.value)
})

const bindGlobalClickEventListener = () => {
	window.addEventListener('click', evt => {
		const visibleDom = document.querySelector('.visible')
		if (!visibleDom || visibleDom.contains(evt.target)) return
		visibleDom.classList.remove('visible');
	},
		{
			capture: true
		}
	)
}


const bindEditorTobarEvent = () => {


	// 2. | 撤销 | 重做 | 格式刷 | 清除格式 |
	const undoDom = document.querySelector('.menu-item__undo');
	undoDom.title = `撤销(${isApple ? '⌘' : 'Ctrl'}+Z)`
	undoDom.onclick = function () {
		editor.value.command.executeUndo()
	};

	const redoDom = document.querySelector('.menu-item__redo');
	redoDom.title = `重做(${isApple ? '⌘' : 'Ctrl'}+Y)`
	redoDom.onclick = function () {
		editor.value.command.executeRedo()
	}

	const painterDom = document.querySelector('.menu-item__painter');

	painterDom.onclick = function () {
		editor.value.command.executePainter({
			isDblclick: false
		})
	}

	painterDom.ondblclick = function () {
		editor.value.command.executePainter({
			isDblclick: true
		})
	}

	const formatDom = document.querySelector('.menu-item__format');
	formatDom.onclick = function () {
		editor.value.command.executeFormat()
	}

	// 3. | 字体 | 字体变大 | 字体变小 | 加粗 | 斜体 | 下划线 | 删除线 | 上标 | 下标 | 字体颜色 | 背景色 |
	const fontDom = document.querySelector('.menu-item__font');
	const fontSelectDom = fontDom.querySelector('.select');
	const fontOptionDom = fontDom.querySelector('.options');
	fontDom.onclick = function () {
		fontOptionDom.classList.toggle('visible')
	}
	fontOptionDom.onclick = function (evt) {
		const li = evt.target
		editor.value.command.executeFont(li.dataset.family);
	}

	const sizeSetDom = document.querySelector('.menu-item__size');
	const sizeSelectDom = sizeSetDom.querySelector('.select');
	const sizeOptionDom = sizeSetDom.querySelector('.options');
	sizeSetDom.title = `设置字号`;
	sizeSetDom.onclick = function () {
		sizeOptionDom.classList.toggle('visible')
	}
	sizeOptionDom.onclick = function (evt) {
		const li = evt.target
		editor.value.command.executeSize(Number(li.dataset.size));
	}
	const sizeAddDom = document.querySelector('.menu-item__size-add');
	sizeAddDom.title = `增大字号(${isApple ? '⌘' : 'Ctrl'}+[)`
	sizeAddDom.onclick = function () {
		editor.value.command.executeSizeAdd()
	}

	const sizeMinusDom = document.querySelector('.menu-item__size-minus');

	sizeMinusDom.title = `减小字号(${isApple ? '⌘' : 'Ctrl'}+])`;

	sizeMinusDom.onclick = function () {
		editor.value.command.executeSizeMinus()
	}

	const boldDom = document.querySelector('.menu-item__bold')
	boldDom.title = `加粗(${isApple ? '⌘' : 'Ctrl'}+B)`
	boldDom.onclick = function () {
		editor.value.command.executeBold()
	}

	const italicDom =
		document.querySelector('.menu-item__italic')
	italicDom.title = `斜体(${isApple ? '⌘' : 'Ctrl'}+I)`
	italicDom.onclick = function () {
		editor.value.command.executeItalic()
	}

	const underlineDom = document.querySelector('.menu-item__underline');
	underlineDom.title = `下划线(${isApple ? '⌘' : 'Ctrl'}+U)`
	underlineDom.onclick = function () {
		console.log('underline')
		editor.value.command.executeUnderline()
	}

	const strikeoutDom = document.querySelector(
		'.menu-item__strikeout'
	)
	strikeoutDom.onclick = function () {
		console.log('strikeout')
		editor.value.command.executeStrikeout()
	}

	const superscriptDom = document.querySelector('.menu-item__superscript')
	superscriptDom.title = `上标(${isApple ? '⌘' : 'Ctrl'}+Shift+,)`
	superscriptDom.onclick = function () {
		editor.value.command.executeSuperscript()
	}

	const subscriptDom = document.querySelector('.menu-item__subscript')
	editor.value.title = `下标(${isApple ? '⌘' : 'Ctrl'}+Shift+.)`
	subscriptDom.onclick = function () {
		editor.value.command.executeSubscript()
	}

	const colorControlDom = document.querySelector('#color')
	colorControlDom.oninput = function () {
		editor.value.command.executeColor(colorControlDom.value)
	}
	const colorDom = document.querySelector('.menu-item__color')
	const colorSpanDom = colorDom.querySelector('span')
	colorDom.onclick = function () {
		colorControlDom.click()
	}
	const highlightControlDom =
		document.querySelector('#highlight')
	highlightControlDom.oninput = function () {
		editor.value.command.executeHighlight(highlightControlDom.value)
	}
	const highlightDom = document.querySelector('.menu-item__highlight')
	const highlightSpanDom = highlightDom.querySelector('span')
	highlightDom.onclick = function () {
		highlightControlDom?.click()
	}

	const titleDom = document.querySelector('.menu-item__title')
	const titleSelectDom = titleDom.querySelector('.select')
	const titleOptionDom = titleDom.querySelector('.options')
	titleOptionDom.querySelectorAll('li').forEach((li, index) => {
		li.title = `Ctrl+${isApple ? 'Option' : 'Alt'}+${index}`
	})
	titleDom.onclick = function () {
		titleOptionDom.classList.toggle('visible')
	}
	titleOptionDom.onclick = function (evt) {
		const li = evt.target;
		const level = li.dataset.level;
		editor.value.command.executeTitle(level || null)
	}

	const leftDom = document.querySelector('.menu-item__left')
	leftDom.title = `左对齐(${isApple ? '⌘' : 'Ctrl'}+L)`
	leftDom.onclick = function () {
		editor.value.command.executeRowFlex(RowFlex.LEFT)
	}
	const centerDom =
		document.querySelector('.menu-item__center')
	centerDom.title = `居中对齐(${isApple ? '⌘' : 'Ctrl'}+E)`
	centerDom.onclick = function () {
		console.log('center')
		editor.value.command.executeRowFlex(RowFlex.CENTER)
	}

	const rightDom = document.querySelector('.menu-item__right')
	rightDom.title = `右对齐(${isApple ? '⌘' : 'Ctrl'}+R)`
	rightDom.onclick = function () {
		editor.value.command.executeRowFlex(RowFlex.RIGHT)
	}

	const alignmentDom = document.querySelector('.menu-item__alignment')
	alignmentDom.title = `两端对齐(${isApple ? '⌘' : 'Ctrl'}+J)`
	alignmentDom.onclick = function () {
		editor.value.command.executeRowFlex(RowFlex.ALIGNMENT)
	}

	const rowMarginDom = document.querySelector('.menu-item__row-margin')
	const rowOptionDom = rowMarginDom.querySelector('.options')
	rowMarginDom.onclick = function () {
		rowOptionDom.classList.toggle('visible')
	}
	rowOptionDom.onclick = function (evt) {
		const li = evt.target
		editor.value.command.executeRowMargin(Number(li.dataset.rowmargin))
	}

	const listDom = document.querySelector('.menu-item__list')
	listDom.title = `列表(${isApple ? '⌘' : 'Ctrl'}+Shift+U)`
	const listOptionDom = listDom.querySelector('.options')
	listDom.onclick = function () {
		listOptionDom.classList.toggle('visible')
	}
	listOptionDom.onclick = function (evt) {
		const li = evt.target;
		const listType = li.dataset.listType;
		const listStyle = (li.dataset.listStyle)
		editor.value.command.executeList(listType, listStyle);
	}

	// 4. | 表格 | 图片 | 超链接 | 分割线 | 水印 | 代码块 | 分隔符 | 控件 | 复选框 | LaTeX | 日期选择器
	const tableDom = document.querySelector('.menu-item__table');
	const tablePanelContainer = document.querySelector('.menu-item__table__collapse');
	const tableClose = document.querySelector('.table-close');
	const tableTitle = document.querySelector('.table-select');
	const tablePanel = document.querySelector('.table-panel');
	// 绘制行列
	const tableCellList = []
	for (let i = 0; i < 10; i++) {
		const tr = document.createElement('tr')
		tr.classList.add('table-row')
		const trCellList = []
		for (let j = 0; j < 10; j++) {
			const td = document.createElement('td')
			td.classList.add('table-cel')
			tr.append(td)
			trCellList.push(td)
		}
		tablePanel.append(tr)
		tableCellList.push(trCellList)
	}
	let colIndex = 0
	let rowIndex = 0

	// 移除所有格选择
	function removeAllTableCellSelect() {
		tableCellList.forEach(tr => {
			tr.forEach(td => td.classList.remove('active'))
		})
	}

	// 设置标题内容
	function setTableTitle(payload) {
		tableTitle.innerText = payload
	}

	// 恢复初始状态
	function recoveryTable() {
		// 还原选择样式、标题、选择行列
		removeAllTableCellSelect()
		setTableTitle('插入')
		colIndex = 0
		rowIndex = 0
		// 隐藏panel
		tablePanelContainer.style.display = 'none'
	}

	tableDom.onclick = function () {
		tablePanelContainer.style.display = 'block'
	}
	tablePanel.onmousemove = function (evt) {
		const celSize = 16
		const rowMarginTop = 10
		const celMarginRight = 6
		const { offsetX, offsetY } = evt
		// 移除所有选择
		removeAllTableCellSelect()
		colIndex = Math.ceil(offsetX / (celSize + celMarginRight)) || 1
		rowIndex = Math.ceil(offsetY / (celSize + rowMarginTop)) || 1
		// 改变选择样式
		tableCellList.forEach((tr, trIndex) => {
			tr.forEach((td, tdIndex) => {
				if (tdIndex < colIndex && trIndex < rowIndex) {
					td.classList.add('active')
				}
			})
		})
		// 改变表格标题
		setTableTitle(`${rowIndex}×${colIndex}`)
	}
	tableClose.onclick = function () {
		recoveryTable()
	}
	tablePanel.onclick = function () {
		// 应用选择
		editor.value.command.executeInsertTable(rowIndex, colIndex)
		recoveryTable()
	}

	const imageDom = document.querySelector('.menu-item__image')
	const imageFileDom = document.querySelector('#image')
	imageDom.onclick = function () {
		imageFileDom.click()
	}
	imageFileDom.onchange = function () {
		const file = imageFileDom.files[0];
		const fileReader = new FileReader()
		fileReader.readAsDataURL(file)
		fileReader.onload = function () {
			// 计算宽高
			const image = new Image()
			const value = fileReader.result;
			image.src = value
			image.onload = function () {
				editor.value.command.executeImage({
					value,
					width: image.width,
					height: image.height
				})
				imageFileDom.value = ''
			}
		}
	}

	const hyperlinkDom = document.querySelector('.menu-item__hyperlink')
	hyperlinkDom.onclick = function () {
		new Dialog({
			title: '超链接',
			data: [
				{
					type: 'text',
					label: '文本',
					name: 'name',
					required: true,
					placeholder: '请输入文本'
				},
				{
					type: 'text',
					label: '链接',
					name: 'url',
					required: true,
					placeholder: '请输入链接'
				}
			],
			onConfirm: payload => {
				const name = payload.find(p => p.name === 'name')?.value
				if (!name) return
				const url = payload.find(p => p.name === 'url')?.value
				if (!url) return
				editor.value.command.executeHyperlink({
					type: ElementType.HYPERLINK,
					value: '',
					url,
					valueList: name.split('').map(n => ({
						value: n,
						size: 16
					}))
				})
			}
		})
	}

	const separatorDom = document.querySelector('.menu-item__separator');
	const separatorOptionDom = separatorDom.querySelector('.options');
	separatorDom.onclick = function () {
		separatorOptionDom.classList.toggle('visible')
	}
	separatorOptionDom.onmousedown = function (evt) {
		let payload = []
		const li = evt.target
		const separatorDash = li.dataset.separator?.split(',').map(Number)
		if (separatorDash) {
			const isSingleLine = separatorDash.every(d => d === 0)
			if (!isSingleLine) {
				payload = separatorDash
			}
		}
		editor.value.command.executeSeparator(payload)
	}

	const pageBreakDom = document.querySelector('.menu-item__page-break');
	pageBreakDom.onclick = function () {
		editor.value.command.executePageBreak()
	}
	const watermarkDom = document.querySelector('.menu-item__watermark');
	const watermarkOptionDom = watermarkDom.querySelector('.options')
	watermarkDom.onclick = function () {
		watermarkOptionDom.classList.toggle('visible')
	}
	watermarkOptionDom.onmousedown = function (evt) {
		const li = evt.target
		const menu = li.dataset.menu;
		watermarkOptionDom.classList.toggle('visible')
		if (menu === 'add') {
			new Dialog({
				title: '水印',
				data: [
					{
						type: 'text',
						label: '内容',
						name: 'data',
						required: true,
						placeholder: '请输入内容'
					},
					{
						type: 'color',
						label: '颜色',
						name: 'color',
						required: true,
						value: '#AEB5C0'
					},
					{
						type: 'number',
						label: '字体大小',
						name: 'size',
						required: true,
						value: '120'
					}
				],
				onConfirm: payload => {
					const nullableIndex = payload.findIndex(p => !p.value)
					if (~nullableIndex) return
					const watermark = payload.reduce((pre, cur) => {
						pre[cur.name] = cur.value
						return pre
					}, {})
					editor.value.command.executeAddWatermark({
						data: watermark.data,
						color: watermark.color,
						size: Number(watermark.size)
					})
				}
			})
		} else {
			editor.value.command.executeDeleteWatermark()
		}
	}

	const codeblockDom = document.querySelector('.menu-item__codeblock');
	codeblockDom.onclick = function () {
		new Dialog({
			title: '代码块',
			data: [
				{
					type: 'textarea',
					name: 'codeblock',
					placeholder: '请输入代码',
					width: 500,
					height: 300
				}
			],
			onConfirm: payload => {
				const codeblock = payload.find(p => p.name === 'codeblock')?.value
				if (!codeblock) return
				const tokenList = prism.tokenize(codeblock, prism.languages.javascript)
				const formatTokenList = formatPrismToken(tokenList)
				const elementList = []
				for (let i = 0; i < formatTokenList.length; i++) {
					const formatToken = formatTokenList[i]
					const tokenStringList = formatToken.content.split('')
					for (let j = 0; j < tokenStringList.length; j++) {
						const value = tokenStringList[j]
						const element = {
							value
						}
						if (formatToken.color) {
							element.color = formatToken.color
						}
						if (formatToken.bold) {
							element.bold = true
						}
						if (formatToken.italic) {
							element.italic = true
						}
						elementList.push(element)
					}
				}
				elementList.unshift({
					value: '\n'
				})
				editor.value.command.executeInsertElementList(elementList)
			}
		})
	}

	const controlDom = document.querySelector('.menu-item__control');
	const controlOptionDom = controlDom.querySelector('.options')
	controlDom.onclick = function () {
		controlOptionDom.classList.toggle('visible')
	}
	controlOptionDom.onmousedown = function (evt) {
		controlOptionDom.classList.toggle('visible')
		const li = evt.target;
		const type = li.dataset.control;
		switch (type) {
			case ControlType.TEXT:
				new Dialog({
					title: '文本控件',
					data: [
						{
							type: 'text',
							label: '占位符',
							name: 'placeholder',
							required: true,
							placeholder: '请输入占位符'
						},
						{
							type: 'text',
							label: '默认值',
							name: 'value',
							placeholder: '请输入默认值'
						}
					],
					onConfirm: payload => {
						const placeholder = payload.find(
							p => p.name === 'placeholder'
						)?.value
						if (!placeholder) return
						const value = payload.find(p => p.name === 'value')?.value || ''
						editor.value.command.executeInsertElementList([
							{
								type: ElementType.CONTROL,
								value: '',
								control: {
									type,
									value: value ? [{
										value
									}]
										: null,
									placeholder
								}
							}
						])
					}
				})
				break
			case ControlType.SELECT:
				new Dialog({
					title: '列举控件',
					data: [
						{
							type: 'text',
							label: '占位符',
							name: 'placeholder',
							required: true,
							placeholder: '请输入占位符'
						},
						{
							type: 'text',
							label: '默认值',
							name: 'code',
							placeholder: '请输入默认值'
						},
						{
							type: 'textarea',
							label: '值集',
							name: 'valueSets',
							required: true,
							height: 100,
							placeholder: `请输入值集JSON，例：\n[{\n"value":"有",\n"code":"98175"\n}]`
						}
					],
					onConfirm: payload => {
						const placeholder = payload.find(
							p => p.name === 'placeholder'
						)?.value
						if (!placeholder) return
						const valueSets = payload.find(p => p.name === 'valueSets')?.value
						if (!valueSets) return
						const code = payload.find(p => p.name === 'code')?.value
						editor.value.command.executeInsertElementList([
							{
								type: ElementType.CONTROL,
								value: '',
								control: {
									type,
									code,
									value: null,
									placeholder,
									valueSets: JSON.parse(valueSets)
								}
							}
						])
					}
				})
				break
			case ControlType.CHECKBOX:
				new Dialog({
					title: '复选框控件',
					data: [
						{
							type: 'text',
							label: '默认值',
							name: 'code',
							placeholder: '请输入默认值，多个值以英文逗号分割'
						},
						{
							type: 'textarea',
							label: '值集',
							name: 'valueSets',
							required: true,
							height: 100,
							placeholder: `请输入值集JSON，例：\n[{\n"value":"有",\n"code":"98175"\n}]`
						}
					],
					onConfirm: payload => {
						const valueSets = payload.find(p => p.name === 'valueSets')?.value
						if (!valueSets) return
						const code = payload.find(p => p.name === 'code')?.value
						editor.value.command.executeInsertElementList([
							{
								type: ElementType.CONTROL,
								value: '',
								control: {
									type,
									code,
									value: null,
									valueSets: JSON.parse(valueSets)
								}
							}
						])
					}
				})
				break
			default:
				break
		}
	}

	const checkboxDom = document.querySelector('.menu-item__checkbox')
	checkboxDom.onclick = function () {
		editor.value.command.executeInsertElementList([
			{
				type: ElementType.CHECKBOX,
				value: ''
			}
		])
	}

	const latexDom = document.querySelector('.menu-item__latex')
	latexDom.onclick = function () {
		new Dialog({
			title: 'LaTeX',
			data: [
				{
					type: 'textarea',
					height: 100,
					name: 'value',
					placeholder: '请输入LaTeX文本'
				}
			],
			onConfirm: payload => {
				const value = payload.find(p => p.name === 'value')?.value
				if (!value) return
				editor.value.command.executeInsertElementList([
					{
						type: ElementType.LATEX,
						value
					}
				])
			}
		})
	}

	const dateDom = document.querySelector('.menu-item__date')
	const dateDomOptionDom = dateDom.querySelector('.options')
	dateDom.onclick = function () {
		dateDomOptionDom.classList.toggle('visible')
		// 定位调整
		const bodyRect = document.body.getBoundingClientRect()
		const dateDomOptionRect = dateDomOptionDom.getBoundingClientRect()
		if (dateDomOptionRect.left + dateDomOptionRect.width > bodyRect.width) {
			dateDomOptionDom.style.right = '0px'
			dateDomOptionDom.style.left = 'unset'
		} else {
			dateDomOptionDom.style.right = 'unset'
			dateDomOptionDom.style.left = '0px'
		}
		// 当前日期
		const date = new Date()
		const year = date.getFullYear().toString()
		const month = (date.getMonth() + 1).toString().padStart(2, '0')
		const day = date.getDate().toString().padStart(2, '0')
		const hour = date.getHours().toString().padStart(2, '0')
		const minute = date.getMinutes().toString().padStart(2, '0')
		const second = date.getSeconds().toString().padStart(2, '0')
		const dateString = `${year}-${month}-${day}`
		const dateTimeString = `${dateString} ${hour}:${minute}:${second}`
		dateDomOptionDom.querySelector('li:first-child').innerText = dateString;
		dateDomOptionDom.querySelector('li:last-child').innerText = dateTimeString
	}
	dateDomOptionDom.onmousedown = function (evt) {
		const li = evt.target
		const dateFormat = li.dataset.format
		dateDomOptionDom.classList.toggle('visible')
		editor.value.command.executeInsertElementList([
			{
				type: ElementType.DATE,
				value: '',
				dateFormat,
				valueList: [
					{
						value: li.innerText.trim()
					}
				]
			}
		])
	}

	const blockDom = document.querySelector('.menu-item__block')
	blockDom.onclick = function () {
		new Dialog({
			title: '内容块',
			data: [
				{
					type: 'select',
					label: '类型',
					name: 'type',
					value: 'iframe',
					required: true,
					options: [
						{
							label: '网址',
							value: 'iframe'
						},
						{
							label: '视频',
							value: 'video'
						}
					]
				},
				{
					type: 'number',
					label: '宽度',
					name: 'width',
					placeholder: '请输入宽度（默认页面内宽度）'
				},
				{
					type: 'number',
					label: '高度',
					name: 'height',
					required: true,
					placeholder: '请输入高度'
				},
				{
					type: 'textarea',
					label: '地址',
					height: 100,
					name: 'value',
					required: true,
					placeholder: '请输入地址'
				}
			],
			onConfirm: payload => {
				const type = payload.find(p => p.name === 'type')?.value
				if (!type) return
				const value = payload.find(p => p.name === 'value')?.value
				if (!value) return
				const width = payload.find(p => p.name === 'width')?.value
				const height = payload.find(p => p.name === 'height')?.value
				if (!height) return
				const block = {
					type: type
				}
				if (block.type === BlockType.IFRAME) {
					block.iframeBlock = {
						src: value
					}
				} else if (block.type === BlockType.VIDEO) {
					block.videoBlock = {
						src: value
					}
				}
				const blockElement = {
					type: ElementType.BLOCK,
					value: '',
					height: Number(height),
					block
				}
				if (width) {
					blockElement.width = Number(width)
				}
				editor.value.command.executeInsertElementList([blockElement])
			}
		})
	}

	// 5. | 搜索&替换 | 打印 |
	const searchCollapseDom = document.querySelector('.menu-item__search__collapse')
	const searchInputDom = document.querySelector('.menu-item__search__collapse__search input')
	const replaceInputDom = document.querySelector('.menu-item__search__collapse__replace input')
	const searchDom = document.querySelector('.menu-item__search')
	searchDom.title = `搜索与替换(${isApple ? '⌘' : 'Ctrl'}+F)`
	const searchResultDom =
		searchCollapseDom.querySelector('.search-result')

	function setSearchResult() {
		const result = editor.value.command.getSearchNavigateInfo();
		if (result) {
			const { index, count } = result
			searchResultDom.innerText = `${index}/${count}`
		} else {
			searchResultDom.innerText = ''
		}
	}

	searchDom.onclick = function () {
		searchCollapseDom.style.display = 'block'
		const bodyRect = document.body.getBoundingClientRect()
		const searchRect = searchDom.getBoundingClientRect()
		const searchCollapseRect = searchCollapseDom.getBoundingClientRect()
		if (searchRect.left + searchCollapseRect.width > bodyRect.width) {
			searchCollapseDom.style.right = '0px'
			searchCollapseDom.style.left = 'unset'
		} else {
			searchCollapseDom.style.right = 'unset'
		}
		searchInputDom.focus()
	}
	searchCollapseDom.querySelector('span').onclick =
		function () {
			searchCollapseDom.style.display = 'none'
			searchInputDom.value = ''
			replaceInputDom.value = ''
			editor.value.command.executeSearch(null)
			setSearchResult()
		}
	searchInputDom.oninput = function () {
		editor.value.command.executeSearch(searchInputDom.value || null)
		setSearchResult()
	}
	searchInputDom.onkeydown = function (evt) {
		if (evt.key === 'Enter') {
			editor.value.command.executeSearch(searchInputDom.value || null)
			setSearchResult()
		}
	}
	searchCollapseDom.querySelector('button').onclick =
		function () {
			const searchValue = searchInputDom.value
			const replaceValue = replaceInputDom.value
			if (searchValue && replaceValue && searchValue !== replaceValue) {
				editor.value.command.executeReplace(replaceValue)
			}
		}
	searchCollapseDom.querySelector('.arrow-left').onclick =
		function () {
			editor.value.command.executeSearchNavigatePre()
			setSearchResult()
		}
	searchCollapseDom.querySelector('.arrow-right').onclick =
		function () {
			editor.value.command.executeSearchNavigateNext()
			setSearchResult()
		}

	const printDom = document.querySelector('.menu-item__print')
	printDom.title = `打印(${isApple ? '⌘' : 'Ctrl'}+P)`
	printDom.onclick = function () {
		editor.value.command.executePrint()
	}

	// 6. 目录显隐 | 页面模式 | 纸张缩放 | 纸张大小 | 纸张方向 | 页边距 | 全屏
	async function updateCatalog() {
		const catalog = await editor.value.command.getCatalog()
		const catalogMainDom = document.querySelector('.catalog__main')
		catalogMainDom.innerHTML = ''
		if (catalog) {
			const appendCatalog = (
				parent,
				catalogItems
			) => {
				for (let c = 0; c < catalogItems.length; c++) {
					const catalogItem = catalogItems[c]
					const catalogItemDom = document.createElement('div')
					catalogItemDom.classList.add('catalog-item')
					// 渲染
					const catalogItemContentDom = document.createElement('div')
					catalogItemContentDom.classList.add('catalog-item__content')
					const catalogItemContentSpanDom = document.createElement('span')
					catalogItemContentSpanDom.innerText = catalogItem.name
					catalogItemContentDom.append(catalogItemContentSpanDom)
					// 定位
					catalogItemContentDom.onclick = () => {
						editor.value.command.executeLocationCatalog(catalogItem.id)
					}
					catalogItemDom.append(catalogItemContentDom)
					if (catalogItem.subCatalog && catalogItem.subCatalog.length) {
						appendCatalog(catalogItemDom, catalogItem.subCatalog)
					}
					// 追加
					parent.append(catalogItemDom)
				}
			}
			appendCatalog(catalogMainDom, catalog)
		}
	}

	let isCatalogShow = true
	const catalogDom = document.querySelector < HTMLElement > ('.catalog')
	const catalogModeDom =
		document.querySelector('.catalog-mode')
	const catalogHeaderCloseDom = document.querySelector('.catalog__header__close')
	const switchCatalog = () => {
		isCatalogShow = !isCatalogShow
		if (isCatalogShow) {
			catalogDom.style.display = 'block'
			updateCatalog()
		} else {
			catalogDom.style.display = 'none'
		}
	}
	catalogModeDom.onclick = switchCatalog
	catalogHeaderCloseDom.onclick = switchCatalog

	const pageModeDom = document.querySelector('.page-mode')
	const pageModeOptionsDom =
		pageModeDom.querySelector('.options')
	pageModeDom.onclick = function () {
		pageModeOptionsDom.classList.toggle('visible')
	}
	pageModeOptionsDom.onclick = function (evt) {
		const li = evt.target
		editor.value.command.executePageMode(li.dataset.pageMode);
	}

	document.querySelector('.page-scale-percentage').onclick = function () {
		editor.value.command.executePageScaleRecovery()
	}

	document.querySelector('.page-scale-minus').onclick = function () {
		editor.value.command.executePageScaleMinus()
	}

	document.querySelector('.page-scale-add').onclick = function () {
		editor.value.command.executePageScaleAdd()
	}
	// 纸张大小
	const paperSizeDom =
		document.querySelector('.paper-size')
	const paperSizeDomOptionsDom =
		paperSizeDom.querySelector('.options')
	paperSizeDom.onclick = function () {
		paperSizeDomOptionsDom.classList.toggle('visible')
	}
	paperSizeDomOptionsDom.onclick = function (evt) {
		const li = evt.target
		const paperType = li.dataset.paperSize
		const [width, height] = paperType.split('*').map(Number)
		editor.value.command.executePaperSize(width, height)
		// 纸张状态回显
		paperSizeDomOptionsDom.querySelectorAll('li').forEach(child => child.classList.remove('active'))
		li.classList.add('active')
	}

	// 纸张方向
	const paperDirectionDom =
		document.querySelector('.paper-direction')
	const paperDirectionDomOptionsDom =
		paperDirectionDom.querySelector('.options')
	paperDirectionDom.onclick = function () {
		paperDirectionDomOptionsDom.classList.toggle('visible')
	}
	paperDirectionDomOptionsDom.onclick = function (evt) {
		const li = evt.target
		const paperDirection = li.dataset.paperDirection
		editor.value.command.executePaperDirection(paperDirection)
		// 纸张方向状态回显
		paperDirectionDomOptionsDom
			.querySelectorAll('li')
			.forEach(child => child.classList.remove('active'))
		li.classList.add('active')
	}

	// 页面边距
	const paperMarginDom =
		document.querySelector('.paper-margin')
	paperMarginDom.onclick = function () {
		const [topMargin, rightMargin, bottomMargin, leftMargin] =
			editor.value.command.getPaperMargin()
		new Dialog({
			title: '页边距',
			data: [
				{
					type: 'text',
					label: '上边距',
					name: 'top',
					required: true,
					value: `${topMargin}`,
					placeholder: '请输入上边距'
				},
				{
					type: 'text',
					label: '下边距',
					name: 'bottom',
					required: true,
					value: `${bottomMargin}`,
					placeholder: '请输入下边距'
				},
				{
					type: 'text',
					label: '左边距',
					name: 'left',
					required: true,
					value: `${leftMargin}`,
					placeholder: '请输入左边距'
				},
				{
					type: 'text',
					label: '右边距',
					name: 'right',
					required: true,
					value: `${rightMargin}`,
					placeholder: '请输入右边距'
				}
			],
			onConfirm: payload => {
				const top = payload.find(p => p.name === 'top')?.value
				if (!top) return
				const bottom = payload.find(p => p.name === 'bottom')?.value
				if (!bottom) return
				const left = payload.find(p => p.name === 'left')?.value
				if (!left) return
				const right = payload.find(p => p.name === 'right')?.value
				if (!right) return
				editor.value.command.executeSetPaperMargin([
					Number(top),
					Number(right),
					Number(bottom),
					Number(left)
				])
			}
		})
	}

	// 全屏
	const fullscreenDom =
		document.querySelector('.fullscreenEditor')
	fullscreenDom.onclick = toggleFullscreen
	window.addEventListener('keydown', evt => {
		if (evt.key === 'F11') {
			toggleFullscreen()
			evt.preventDefault()
		}
	})
	document.addEventListener('fullscreenchange', () => {
		fullscreenDom.classList.toggle('exist')
	})

	function toggleFullscreen() {
		if (!document.fullscreenElement) {
			document.documentElement.requestFullscreen()
		} else {
			document.exitFullscreen()
		}
	}

	// 7. 编辑器使用模式
	let modeIndex = 0
	const modeList = [
		{
			mode: EditorMode.EDIT,
			name: '编辑模式'
		},
		{
			mode: EditorMode.CLEAN,
			name: '清洁模式'
		},
		{
			mode: EditorMode.READONLY,
			name: '只读模式'
		},
		{
			mode: EditorMode.FORM,
			name: '表单模式'
		},
		{
			mode: EditorMode.PRINT,
			name: '打印模式'
		}
	]
	const modeElement = document.querySelector('.editor-mode')
	modeElement.onclick = function () {
		// 模式选择循环
		modeIndex === modeList.length - 1 ? (modeIndex = 0) : modeIndex++
		// 设置模式
		const { name, mode } = modeList[modeIndex]
		modeElement.innerText = name
		editor.value.command.executeMode(mode)
		// 设置菜单栏权限视觉反馈
		const isReadonly = mode === EditorMode.READONLY
		const enableMenuList = ['search', 'print']
		document.querySelectorAll('.menu-item>div').forEach(dom => {
			const menu = dom.dataset.menu
			isReadonly && (!menu || !enableMenuList.includes(menu))
				? dom.classList.add('disable')
				: dom.classList.remove('disable')
		})
	}

	// 模拟批注
	const commentDom = document.querySelector('.comment')

	async function updateComment() {
		const groupIds = await editor.value.command.getGroupIds()
		for (const comment of commentList.value) {
			const activeCommentDom = commentDom.querySelector(
				`.comment-item[data-id='${comment.id}']`
			)
			// 编辑器是否存在对应成组id
			if (groupIds.includes(comment.id)) {
				// 当前dom是否存在-不存在则追加
				if (!activeCommentDom) {
					const commentItem = document.createElement('div')
					commentItem.classList.add('comment-item')
					commentItem.setAttribute('data-id', comment.id)
					commentItem.onclick = () => {
						editor.value.command.executeLocationGroup(comment.id)
					}
					commentDom.append(commentItem)
					// 选区信息
					const commentItemTitle = document.createElement('div')
					commentItemTitle.classList.add('comment-item__title')
					commentItemTitle.append(document.createElement('span'))
					const commentItemTitleContent = document.createElement('span')
					commentItemTitleContent.innerText = comment.rangeText
					commentItemTitle.append(commentItemTitleContent)
					const closeDom = document.createElement('i')
					closeDom.onclick = () => {
						editor.value.command.executeDeleteGroup(comment.id)
					}
					commentItemTitle.append(closeDom)
					commentItem.append(commentItemTitle)
					// 基础信息
					const commentItemInfo = document.createElement('div')
					commentItemInfo.classList.add('comment-item__info')
					const commentItemInfoName = document.createElement('span')
					commentItemInfoName.innerText = comment.userName
					const commentItemInfoDate = document.createElement('span')
					commentItemInfoDate.innerText = comment.createdDate
					commentItemInfo.append(commentItemInfoName)
					commentItemInfo.append(commentItemInfoDate)
					commentItem.append(commentItemInfo)
					// 详细评论
					const commentItemContent = document.createElement('div')
					commentItemContent.classList.add('comment-item__content')
					commentItemContent.innerText = comment.content
					commentItem.append(commentItemContent)
					commentDom.append(commentItem)
				}
			} else {
				// 编辑器内不存在对应成组id则dom则移除
				activeCommentDom?.remove()
			}
		}
	}

	// 8. 内部事件监听
	editor.value.listener.rangeStyleChange = function (payload) {
		// 控件类型
		payload.type === ElementType.SUBSCRIPT
			? subscriptDom.classList.add('active')
			: subscriptDom.classList.remove('active')
		payload.type === ElementType.SUPERSCRIPT
			? superscriptDom.classList.add('active')
			: superscriptDom.classList.remove('active')
		payload.type === ElementType.SEPARATOR
			? separatorDom.classList.add('active')
			: separatorDom.classList.remove('active')
		separatorOptionDom
			.querySelectorAll('li')
			.forEach(li => li.classList.remove('active'))
		if (payload.type === ElementType.SEPARATOR) {
			const separator = payload.dashArray.join(',') || '0,0'
			const curSeparatorDom = separatorOptionDom.querySelector(
				`[data-separator='${separator}']`
			)
			if (curSeparatorDom) {
				curSeparatorDom.classList.add('active')
			}
		}

		// 富文本
		fontOptionDom
			.querySelectorAll('li')
			.forEach(li => li.classList.remove('active'))
		const curFontDom = fontOptionDom.querySelector(
			`[data-family='${payload.font}']`
		)
		if (curFontDom) {
			fontSelectDom.innerText = curFontDom.innerText
			fontSelectDom.style.fontFamily = payload.font
			curFontDom.classList.add('active')
		}
		sizeOptionDom
			.querySelectorAll('li')
			.forEach(li => li.classList.remove('active'))
		const curSizeDom = sizeOptionDom.querySelector(
			`[data-size='${payload.size}']`
		)
		if (curSizeDom) {
			sizeSelectDom.innerText = curSizeDom.innerText
			curSizeDom.classList.add('active')
		} else {
			sizeSelectDom.innerText = `${payload.size}`
		}
		payload.bold
			? boldDom.classList.add('active')
			: boldDom.classList.remove('active')
		payload.italic
			? italicDom.classList.add('active')
			: italicDom.classList.remove('active')
		payload.underline
			? underlineDom.classList.add('active')
			: underlineDom.classList.remove('active')
		payload.strikeout
			? strikeoutDom.classList.add('active')
			: strikeoutDom.classList.remove('active')
		if (payload.color) {
			colorDom.classList.add('active')
			colorControlDom.value = payload.color
			colorSpanDom.style.backgroundColor = payload.color
		} else {
			colorDom.classList.remove('active')
			colorControlDom.value = '#000000'
			colorSpanDom.style.backgroundColor = '#000000'
		}
		if (payload.highlight) {
			highlightDom.classList.add('active')
			highlightControlDom.value = payload.highlight
			highlightSpanDom.style.backgroundColor = payload.highlight
		} else {
			highlightDom.classList.remove('active')
			highlightControlDom.value = '#ffff00'
			highlightSpanDom.style.backgroundColor = '#ffff00'
		}

		// 行布局
		leftDom.classList.remove('active')
		centerDom.classList.remove('active')
		rightDom.classList.remove('active')
		alignmentDom.classList.remove('active')
		if (payload.rowFlex && payload.rowFlex === 'right') {
			rightDom.classList.add('active')
		} else if (payload.rowFlex && payload.rowFlex === 'center') {
			centerDom.classList.add('active')
		} else if (payload.rowFlex && payload.rowFlex === 'alignment') {
			alignmentDom.classList.add('active')
		} else {
			leftDom.classList.add('active')
		}

		// 行间距
		rowOptionDom
			.querySelectorAll('li')
			.forEach(li => li.classList.remove('active'))
		const curRowMarginDom = rowOptionDom.querySelector(
			`[data-rowmargin='${payload.rowMargin}']`
		)
		!
			curRowMarginDom.classList.add('active')

		// 功能
		payload.undo
			? undoDom.classList.remove('no-allow')
			: undoDom.classList.add('no-allow')
		payload.redo
			? redoDom.classList.remove('no-allow')
			: redoDom.classList.add('no-allow')
		payload.painter
			? painterDom.classList.add('active')
			: painterDom.classList.remove('active')

		// 标题
		titleOptionDom
			.querySelectorAll('li')
			.forEach(li => li.classList.remove('active'))
		if (payload.level) {
			const curTitleDom = titleOptionDom.querySelector(
				`[data-level='${payload.level}']`
			)
			titleSelectDom.innerText = curTitleDom.innerText
			curTitleDom.classList.add('active')
		} else {
			titleSelectDom.innerText = '正文'
			titleOptionDom.querySelector('li:first-child').classList.add('active')
		}

		// 列表
		listOptionDom
			.querySelectorAll('li')
			.forEach(li => li.classList.remove('active'))
		if (payload.listType) {
			listDom.classList.add('active')
			const listType = payload.listType
			const listStyle =
				payload.listType === ListType.OL ? ListStyle.DECIMAL : payload.listType
			const curListDom = listOptionDom.querySelector(
				`[data-list-type='${listType}'][data-list-style='${listStyle}']`
			)
			if (curListDom) {
				curListDom.classList.add('active')
			}
		} else {
			listDom.classList.remove('active')
		}

		// 批注
		commentDom
			.querySelectorAll('.comment-item')
			.forEach(commentItemDom => {
				commentItemDom.classList.remove('active')
			})
		if (payload.groupIds) {
			const [id] = payload.groupIds
			const activeCommentDom = commentDom.querySelector(
				`.comment-item[data-id='${id}']`
			)
			if (activeCommentDom) {
				activeCommentDom.classList.add('active')
				scrollIntoView(commentDom, activeCommentDom)
			}
		}
	}

	editor.value.listener.visiblePageNoListChange
		= function (payload) {
			const text = payload.map(i => i + 1).join('、')
			document.querySelector('.page-no-list').innerText = text
		}

	editor.value.listener.pageSizeChange =
		function (payload) {
			document.querySelector(
				'.page-size'
			).innerText = `${payload}`
		}

	editor.value.listener.intersectionPageNoChange
		= function (payload) {
			document.querySelector('.page-no').innerText = `${payload + 1
				}`
		}

	editor.value.listener.pageScaleChange =
		function (payload) {
			document.querySelector(
				'.page-scale-percentage'
			).innerText = `${Math.floor(payload * 10 * 10)}%`
		}

	editor.value.listener.controlChange =
		function (payload) {
			const disableMenusInControlContext = [
				'table',
				'hyperlink',
				'separator',
				'page-break'
			]
			// 菜单操作权限
			disableMenusInControlContext.forEach(menu => {
				const menuDom = document.querySelector(
					`.menu-item__${menu}`
				);
				payload ? menuDom.classList.add('disable') : menuDom.classList.remove('disable')
			})
		}

	editor.value.listener.pageModeChange =
		function (payload) {
			const activeMode = pageModeOptionsDom.querySelector(
				`[data-page-mode='${payload}']`
			)
			pageModeOptionsDom
				.querySelectorAll('li')
				.forEach(li => li.classList.remove('active'))
			activeMode.classList.add('active')
		}

	const handleContentChange = async function () {
		// 字数
		const wordCount = await editor.value.command.getWordCount()
		document.querySelector('.word-count').innerText = `${wordCount || 0
			}`
		// 目录
		if (isCatalogShow) {
			nextTick(() => {
				updateCatalog()
			})
		}
		// 批注
		nextTick(() => {
			updateComment()
		})
	}
	editor.value.listener.contentChange = debounce(handleContentChange, 200)
	handleContentChange()

	editor.value.listener.saved = function
		(payload) {
		console.log('elementList: ', payload)
	}

	// 9. 右键菜单注册
	editor.value.register.contextMenuList([
		{
			name: '批注',
			when: payload => {
				return (
					!payload.isReadonly &&
					payload.editorHasSelection &&
					payload.zone === EditorZone.MAIN
				)
			},
			callback: (command) => {
				new Dialog({
					title: '批注',
					data: [
						{
							type: 'textarea',
							label: '批注',
							height: 100,
							name: 'value',
							required: true,
							placeholder: '请输入批注'
						}
					],
					onConfirm: payload => {
						const value = payload.find(p => p.name === 'value')?.value
						if (!value) return
						const groupId = command.executeSetGroup()
						if (!groupId) return
						commentList.value.push({
							id: groupId,
							content: value,
							userName: 'Hufe',
							rangeText: command.getRangeText(),
							createdDate: new Date().toLocaleString()
						})
					}
				})
			}
		},
		{
			name: '签名',
			icon: 'signature',
			when: payload => {
				return !payload.isReadonly && payload.editorTextFocus
			},
			callback: (command) => {
				new Signature({
					onConfirm(payload) {
						if (!payload) return
						const { value, width, height } = payload
						if (!value || !width || !height) return
						command.executeInsertElementList([
							{
								value,
								width,
								height,
								type: ElementType.IMAGE
							}
						])
					}
				})
			}
		},
		{
			name: '格式整理',
			icon: 'word-tool',
			when: payload => {
				return !payload.isReadonly
			},
			callback: (command) => {
				command.executeWordTool()
			}
		},
		{
			name: 'AI提问',
			icon: 'ai',
			when: payload => {
				return !payload.isReadonly
			},
			callback: (command) => {
				// command.executeWordTool()
				//getRangeText
				clearHistory();
				const message = command.getRangeText();
				console.log(message)
				if (!message) {
					return
				}
				const rangeRow = editor.value.command.getRangeContext();
				//图片
				if (rangeRow?.endElement?.type == 'image') {

				}
				inputMessage.value = message;
				aiSendMessage();

			}
		},
		{
			name: 'AI续问',
			icon: 'ai',
			when: payload => {
				return !payload.isReadonly
			},
			callback: (command) => {
				const message = command.getRangeText();
				if (!message) {
					return
				}
				console.log(message);
				inputMessage.value = message;
				aiSendMessage();

			}
		},
		{
			name: 'AI绘图',
			icon: 'word-tool',
			when: payload => {
				return !payload.isReadonly
			},
			callback: (command) => {
				proxy.$Message.info("暂未实现");
				// command.executeWordTool()
			}
		}
	])

	// 10. 快捷键注册
	editor.value.register.shortcutList([
		{
			key: KeyMap.P,
			mod: true,
			isGlobal: true,
			callback: (command) => {
				command.executePrint()
			}
		},
		{
			key: KeyMap.F,
			mod: true,
			isGlobal: true,
			callback: (command) => {
				const text = command.getRangeText()
				searchDom.click()
				if (text) {
					searchInputDom.value = text
					editor.value.command.executeSearch(text)
					setSearchResult()
				}
			}
		},
		{
			key: KeyMap.MINUS,
			ctrl: true,
			isGlobal: true,
			callback: (command) => {
				command.executePageScaleMinus()
			}
		},
		{
			key: KeyMap.EQUAL,
			ctrl: true,
			isGlobal: true,
			callback: (command) => {
				command.executePageScaleAdd()
			}
		},
		{
			key: KeyMap.ZERO,
			ctrl: true,
			isGlobal: true,
			callback: (command) => {
				command.executePageScaleRecovery()
			}
		}
	])
}
</script>
<style scoped>
.propClass {
	margin-top: 5px;
	height: 400px;
}
</style>
